﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
using EzDesk.Core.Data;
using EzDesk.Core.Model;
using System.Web.Security;
using EzDesk.DevHelper.DebugLibrary.Helper;
using System.Data.Odbc;
using System.Xml.Linq;
using EzDesk.Utility.Extensions;
using EzDesk.Utility.Generic;
using EzDesk.Utility.Web.Extensions;
using EzDesk.Utility;

namespace EzDesk.DevHelper.DebugLibrary
{

    public class EzDeskInitial : IEzDeskInitial
    {
        private const string FEED_TEMPLATES_FILENAME = "EzDeskFeedTemplates.xml";
        private const string APP_FUNCTIONS_FILENAME = "EzDeskAppFunctions.xml";
        private const string CORE_INFO_FILENAME = "EzDeskCoreInfo.xml";

        private List<SimpleUser> _allUsers = new List<SimpleUser>();

        protected EzDeskDatabaseContainer db = new EzDeskDatabaseContainer();
        List<IEzDeskInitial> initials = new List<IEzDeskInitial>();


        Guid bossGroupId = Guid.NewGuid();
        Guid hrGroupId = Guid.NewGuid();

        Guid auditLeavePermissionId = Guid.NewGuid();
        Guid hrPermissionId = Guid.NewGuid();

        Guid createProjectPermissionId = Guid.NewGuid();

       

        protected void InitialFeedsTemplate(string xmlFileName)
        {

                XElement rootElement = XElement.Load(xmlFileName);
                var feeds = rootElement.Elements();
                foreach (var feed in feeds)
                {
                    Guid id = Guid.Empty;
                    if (feed.Element("id") != null)
                    {
                        id = new Guid(feed.Element("id").Value);
                    }
                    string templateName = null;
                    if (feed.Element("name") != null)
                    {
                        templateName = feed.Element("name").Value;
                    }
                    string title = null;
                    if (feed.Element("title") != null)
                    {
                        title = feed.Element("title").Value;
                    }
                    string body = null;
                    if (feed.Element("body") != null)
                    {
                        body = feed.Element("body").Value;
                    }
                    int type = 0;
                    if (feed.Element("type") != null)
                    {
                        type = Int32.Parse(feed.Element("type").Value);
                    }
                    string templateIcon = "";
                    if (feed.Element("templateIcon") != null)
                    {
                        templateIcon = feed.Element("templateIcon").Value;
                    }

                    db.FeedTemplateSet.AddObject(
                        new FeedTemplate()
                            {
                                Id = id,
                                TemplateName = templateName,
                                Title = title,
                                Body = body,
                                DefaultTypeValue = type,
                                TemplateIconName = templateIcon,
                            }
                        );
                }
                db.SaveChanges();

        }


        protected void CreatPermissions()
        {
            Debug.WriteLine("开始创建默认包含的权限");

            XElement rootEle = XElement.Load(CORE_INFO_FILENAME);
            var permissionsEle = rootEle.Element("permissions");
            foreach (var permissionEle in permissionsEle.Elements())
            {
                var permissionName = permissionEle.Element("name").Value;
                var permissionDescription = permissionEle.Element("description").Value;
                var defaultDeny = permissionEle.Element("defaultDeny").Value;
                var permission = new Permission()
                                     {
                                         Id = Guid.NewGuid(),
                                         DefaultDeny = defaultDeny == "true",
                                         Description = permissionDescription,
                                         Name = permissionName
                                     };
                db.PermissionSet.AddObject(permission);

                var groupNames = permissionEle.Element("groups").Elements().Select(p => p.Value).ToList();

                foreach (var groupName in groupNames)
                {
                    var group = db.GroupSet.FirstOrDefault(p => p.Name == groupName);
                    if (group != null)
                    {
                        var entity = new Permission_Group()
                        {
                            GroupId = group.Id,
                            PermissionId = permission.Id,
                            HasPermission = true,
                        };
                        db.Permission_GroupSet.AddObject(entity);
                    }
                }
            }
          
            db.SaveChanges();

            Debug.WriteLine("权限创建结束");



        }

        protected void CreateAppFunctions(string xmlFileName)
        {

            #region [ AppFunction Types ]
            // 创建 AppFunctions 类型
            Debug.WriteLine("开始创建AppFunctionType");


            XElement typeElement = XElement.Load(xmlFileName);
            var types = typeElement.Element("Types").Elements();
            foreach (var type in types)
            {
                Guid appFunctionTypeID = Guid.Empty;
                if (type.Element("AppFunctionTypeId") != null)
                {
                    appFunctionTypeID = new Guid(type.Element("AppFunctionTypeId").Value);
                }
                string typeName = "";
                if (type.Element("TypeName") != null)
                {
                    typeName = type.Element("TypeName").Value;
                }
                string displayText = "";
                if (type.Element("DisplayText") != null)
                {
                    displayText = type.Element("DisplayText").Value;
                }
                string iconName = "";
                if (type.Element("IconName") != null)
                {
                    iconName = type.Element("IconName").Value;
                }

                int privilege = 0;
                if (type.Element("Privilege") != null)
                {
                    privilege = Int32.Parse(type.Element("Privilege").Value);
                }


                db.AppFunctionTypeSet.AddObject(
                    new AppFunctionType()
                        {
                            Id = appFunctionTypeID,
                            TypeName = typeName,
                            DisplayText = displayText,
                            IconName = iconName,
                            Privilege = privilege

                        }
                    );
            }
            db.SaveChanges();

            Debug.WriteLine("AppFunctionType创建完成");

            #endregion

            #region [ App Functions ]

            Debug.WriteLine("开始创建AppFunctions");
            XElement rootElement = XElement.Load(xmlFileName);
            var functions = rootElement.Element("Functions").Elements();
            foreach (var function in functions)
            {
                Guid appFunctionId = Guid.Empty;
                if (function.Element("AppFunctionId") != null)
                {
                    appFunctionId = new Guid(function.Element("AppFunctionId").Value);
                }
                string appName = "";
                if (function.Element("AppName") != null)
                {
                    appName = function.Element("AppName").Value;
                }
                Guid functionTypeId = Guid.Empty;
                if (function.Element("FunctionTypeId") != null)
                {
                    functionTypeId = new Guid(function.Element("FunctionTypeId").Value);
                }
                Guid functionCategoryId = Guid.Empty;
                if (function.Element("FunctionCategoryId") != null)
                {
                    functionCategoryId = new Guid(function.Element("FunctionCategoryId").Value);
                }
                string title = "";
                if (function.Element("Title") != null)
                {
                    title = function.Element("Title").Value;
                }
                string description = "";
                if (function.Element("Description") != null)
                {
                    description = function.Element("Description").Value;
                }
                string iconName = "";
                if (function.Element("IconName") != null)
                {
                    iconName = function.Element("IconName").Value;
                }
                string funcUrl = "";
                if (function.Element("FuncUrl") != null)
                {
                    funcUrl = function.Element("FuncUrl").Value;
                }
                int privilege = 0;
                if (function.Element("Privilege") != null)
                {
                    privilege = Int32.Parse(function.Element("Privilege").Value);
                }
                string permissionNeed = null;
                if (function.Element("PermissionNeed") != null)
                {
                    permissionNeed = function.Element("PermissionNeed").Value;
                }
                string userAgent = "";
                if (function.Element("UserAgent") != null)
                {
                    userAgent = function.Element("UserAgent").Value;
                }

                db.AppFunctionSet.AddObject(
                    new AppFunction()
                        {
                            Id = appFunctionId,
                            AppName = appName,
                            FunctionTypeId = functionTypeId,
                            FunctionCategoryId = functionCategoryId,
                            Title = title,
                            Description = description,
                            IconName = iconName,
                            FuncUrl = funcUrl,
                            Privilege = privilege,
                            PermissionNeed = permissionNeed,
                            UserAgent = userAgent
                        }
                    );
            }
            db.SaveChanges();

            Debug.WriteLine("AppFuncitons创建完成");

            #endregion
        }

        private void ImportBasicDataFromDb()
        {
            CleanupMembershipData();

            Dictionary<string, Guid> positionDict = new Dictionary<string, Guid>();
            Dictionary<string, Guid> deptDict = new Dictionary<string, Guid>();

            string connStr = @"Driver={Microsoft Access Driver (*.mdb)};Dbq=EzDeskInit.mdb";
            using (OdbcConnection conn = new OdbcConnection(connStr))
            {
                conn.Open();

                // 导入部门
                string sqlStr = "SELECT * FROM dept ";
                OdbcCommand cmd = new OdbcCommand(sqlStr, conn);
                OdbcDataReader dr = cmd.ExecuteReader();
                while (dr.Read())
                {
                    Guid newDeptId = Guid.NewGuid();
                    db.DeptSet.AddObject(
                        new Dept()
                            {
                                Id = newDeptId,
                                DeptName = dr["dept"] as string,
                            }
                        );
                    deptDict.Add(dr["dept"] as string, newDeptId);
                }
                db.SaveChanges();
                Debug.WriteLine("部门 导入完毕！");


                // 导入职位
                sqlStr = "SELECT * FROM userlevel ";
                cmd = new OdbcCommand(sqlStr, conn);
                dr = cmd.ExecuteReader();
                while (dr.Read())
                {
                    Guid newPosId = Guid.NewGuid();
                    db.PositionSet.AddObject(
                        new Position()
                            {
                                Id = newPosId,
                                Priority = (int)dr["pri"],
                                Description = dr["userlevel"] as string,
                            }
                        );
                    positionDict.Add(dr["userlevel"] as string, newPosId);
                }
                db.SaveChanges();
                Debug.WriteLine("职位 导入完毕！");

                
                //导入人员

                

                sqlStr = "SELECT * FROM userinf ";
                cmd = new OdbcCommand(sqlStr, conn);
                dr = cmd.ExecuteReader();
                while (dr.Read())
                {
                    string username = dr["username"] as string;
                    string name = dr["name"] as string;
                    Membership.CreateUser(username, "123456", "xx@@@.com");

                    //固定几个User的UserId，供测试用：
                    Guid newUserId = Guid.NewGuid();
                    switch (name)
                    {
                        case "严兰兰":
                            newUserId = new Guid("877c3323-17a7-42d1-9d75-402ffc894e63");
                            break;
                        case "贺旭华":
                            newUserId = new Guid("06F1962D-5B9E-481D-8C5A-0278506B0677");
                            break;
                        case "黄冠":
                            newUserId = new Guid("ED910B54-0E87-4A61-8DF0-07A0397769A4");
                            break;
                        case "杨裕欣":
                            newUserId = new Guid("05659F3A-404A-48E6-9BF5-C0853C9FD75F");
                            break;
                        case "孔令连":
                            newUserId = new Guid("0c9d7c0c-04a5-4ae2-97a1-d7bbc38f5c66");
                            break;
                        case "杨鑫诚":
                            newUserId = new Guid("37595596-9669-4CC9-B1DB-74F48A31B230");
                            break;
                    }
                    var userProfile = new UserProfile()
                                          {
                                              Id = newUserId,
                                              DeptId = deptDict[dr["userdept"] as string],
                                              PositionId = positionDict[dr["userlevel"] as string],
                                              UserCode = username,
                                              Name = name,
                                          };
                    db.UserProfileSet.AddObject(userProfile);
                    _allUsers.Add(userProfile.ToSimpleUser());
                }
                db.SaveChanges();
                Debug.WriteLine("人员 导入完毕！");


                sqlStr = "SELECT * FROM company ";
                cmd = new OdbcCommand(sqlStr, conn);
                dr = cmd.ExecuteReader();
                dr.Read();

                Debug.WriteLine("开始添加 Org 信息...");

                var epochstr = ((DateTime)dr["exp"]).ToEpoch().ToString() + "weimar";

                var expStr = Des.EncryptDES(epochstr, "weimargr");


                db.OrganizationSet.AddObject(new Organization()
                {
                    Id = Guid.NewGuid(),
                    Icon = dr["logo"] as string,
                    FullName = dr["name"] as string,
                    ShortName = dr["s_name"] as string,
                    UpdateOn = DateTime.Now,
                    Exp = expStr,
                });
                db.SaveChanges();

                Debug.WriteLine("Org 信息添加完成");

                // cache users
                
            }
        }



        private void CreateBasicGroups()
        {
            // 建立系统分组
            db.GroupSet.AddObject(
                new Group()
                    {
                        Id = Guid.NewGuid(),
                        Memberstring = "everyone",
                        Description = "所有人",
                        Type = 0,
                        /* Type = 2, 系统组 */
                        Name = "core_everyone"
                    });
            db.SaveChanges();
            Debug.WriteLine("所有人 分组建立完成");

            //建立各部门分组
            var depts = from d in db.DeptSet
                        select d;
            foreach (var dept in depts)
            {
                List<string> usersInDept =
                    db.UserProfileSet.Where(p => p.DeptId == dept.Id).ToList().Select(p => p.Id.ToString()).ToList();

                Guid newGroupId = Guid.NewGuid();
                db.GroupSet.AddObject(
                    new Group()
                    {
                        Id = newGroupId,
                        Memberstring = GroupMemeberStrHelper.GetGroupMemberStrFromList(usersInDept, null),
                        Description = dept.DeptName,
                        Type = 1,
                        /* 公司部门分组 */
                        Name = dept.Id.ToString(),
                    });
            }
            db.SaveChanges();

            Debug.WriteLine("各部门分组建立完成");
            
            // 建立 用户权限组
            Debug.WriteLine("开始建立用户权限组");

            XElement rootEle = XElement.Load(CORE_INFO_FILENAME);
            var permissionGroupsEle = rootEle.Element("permissionGroups");
            foreach(var permissionGroupEle in permissionGroupsEle.Elements())
            {
                var groupName = permissionGroupEle.Element("name").Value;
                var groupDescription = permissionGroupEle.Element("description").Value;
                string memberstring = "";
                if (permissionGroupEle.Element("groupUsers").HasElements)
                {
                    var userIdArray = new List<Guid>();
                    var userNameList = permissionGroupEle.Element("groupUsers").Element("users").Elements().Select(p => p.Value).ToList();
                    memberstring = getMemberstringFromUserNameList(userNameList, _allUsers, userIdArray);
                }
                else
                {
                    memberstring = permissionGroupEle.Element("groupUsers").Value;
                }
                var theGroup = new Group()
                                    {
                                        Id = Guid.NewGuid(),
                                        Description = groupDescription,
                                        Memberstring = memberstring,
                                        Type = 2,
                                        Name = groupName
                                    };
                db.GroupSet.AddObject(theGroup);
            }
            db.SaveChanges();
            Debug.WriteLine("用户权限组建立完成");
        }

        private string getMemberstringFromUserNameList(List<string> userNameList,List<SimpleUser> allUsers, List<Guid> userIdArray)
        {
            string memberstring;
            foreach (var userName in userNameList)
            {
                var user = allUsers.FirstOrDefault(p => p.UserName == userName);
                if(user != null)
                {
                    userIdArray.Add(user.Id);
                }
            }
            memberstring = userIdArray.Join(",");
            return memberstring;
        }

        #region IEzDeskInitial Members

        void IEzDeskInitial.Initialize()
        {
            //清空数据库
            CleanupDatabase();

            //删除Membership中所有注册信息
            ImportBasicDataFromDb();

            // 初始化公司信息等
            InitializeGlobleInfo();

            Debug.WriteLine("正在导入 FeedTemplate 数据");
            InitialFeedsTemplate(FEED_TEMPLATES_FILENAME);
            Debug.WriteLine("导入 FeedTemplate 数据结束");

            //建立分组
            CreateBasicGroups();

            // 建立Permission基本信息
            CreatPermissions();

            // 建立AppFunctions基本信息
            CreateAppFunctions(APP_FUNCTIONS_FILENAME);

            foreach (var init in initials)
            {
                init.Initialize();
            }

            Debug.WriteLine("完成!");
        }

        private void InitializeGlobleInfo()
        {

        }
        


        public void AddInitializeModule(IEzDeskInitial initial)
        {
            initials.Add(initial);
        }

        #endregion




        private static void CleanupMembershipData()
        {
            Debug.WriteLine("清除MemberShip数据库");
            MembershipUserCollection users = Membership.GetAllUsers();
            foreach (MembershipUser user in users)
            {
                Membership.DeleteUser(user.UserName);
            }
            Debug.WriteLine("MemberShip用户全部清除!");
        }

        private void CleanupDatabase()
        {
            // 
            db.DeleteTable("Feed_RecipientSet");
            db.DeleteTable("Feed_RecordSet");

            //清空Feed
            db.DeleteTable("FeedSet");

            Debug.WriteLine("提醒全部清空!");


            //清空Feed模板
            db.DeleteTable("FeedTemplateSet");
            Debug.WriteLine("Feeds模板全部清除!");

            db.DeleteTable("UserProfileSet");
            //清空人员
            Debug.WriteLine("人员信息全部清空！");

            //清空UserHeadImage
            db.DeleteTable("UserHeadImageSet");
            Debug.WriteLine("UserHeadImage信息已经全部清除!");


            db.DeleteTable("Permission_GroupSet");
            //清空权限_组表
            Debug.WriteLine("权限_组信息已经全部清除!");


            //清空部门
            db.DeleteTable("DeptSet");
            Debug.WriteLine("部门信息已经全部清除!");

            //清空分组
            db.DeleteTable("GroupSet");
            Debug.WriteLine("分组数据全部清除!");

            //清空职位
            db.DeleteTable("PositionSet");
            Debug.WriteLine("职位信息已经全部清除!");

            //清空权限
            db.DeleteTable("PermissionSet");
            Debug.WriteLine("权限信息已经全部清除!");


            //清空AppFunction
            db.DeleteTable("AppFunctionSet");
            Debug.WriteLine("AppFunction信息已经全部清除!");

            //清空AppFunctionType
            db.DeleteTable("AppFunctionTypeSet");
            Debug.WriteLine("AppFunctionTypes信息已经全部清除!");

            //清空AppFunction_user
            db.DeleteTable("AppFunctionShortcutSet");
            Debug.WriteLine("AppFunctionShortcuts信息已经全部清除!");

            //清空Organization
            db.DeleteTable("OrganizationSet");
            Debug.WriteLine("ez_Organizations信息已经全部清除!");

        }


    }



}
